package cn.tramy.pinxian.wind.configuration

import cn.tramy.pinxian.wind.command.CommandBus
import cn.tramy.pinxian.wind.command.DefaultCommandBus
import cn.tramy.pinxian.wind.command.dispatch.CommandDispatcher
import cn.tramy.pinxian.wind.event.DefaultEventBus
import cn.tramy.pinxian.wind.event.EventBus
import cn.tramy.pinxian.wind.event.dispatcher.EventDispatcher
import cn.tramy.pinxian.wind.eventstore.DefaultEventStore
import cn.tramy.pinxian.wind.eventstore.EventStore
import cn.tramy.pinxian.wind.eventstore.query.entry.DomainEventEntryRepository
import cn.tramy.pinxian.wind.eventstore.storage.EventStorage
import cn.tramy.pinxian.wind.eventstore.storage.JpaEventStorage
import cn.tramy.pinxian.wind.handler.registry.HandlerRegistry
import cn.tramy.pinxian.wind.util.WindApplicationUtil
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.context.annotation.Bean

class WindAutoConfiguration : ApplicationContextAware {
    override fun setApplicationContext(applicationContext: ApplicationContext) {
        WindApplicationUtil.applicationContext = applicationContext
    }

    @Bean
    fun commandBus(commandDispatcher: CommandDispatcher): CommandBus = DefaultCommandBus(commandDispatcher)

    @Bean
    fun commandDispatcher(handlerRegistry: HandlerRegistry, eventBus: EventBus): CommandDispatcher = CommandDispatcher(handlerRegistry)

    @Bean
    fun eventDispatcher(handlerRegistry: HandlerRegistry): EventDispatcher = EventDispatcher(handlerRegistry)

    @Bean
    fun eventBus(eventDispatcher: EventDispatcher, eventStore: EventStore): EventBus = DefaultEventBus(eventDispatcher)

    @Bean
    fun eventStore(eventStorage: EventStorage): EventStore = DefaultEventStore(eventStorage)

    @Bean
    fun eventStorage(domainEventEntryRepository: DomainEventEntryRepository): EventStorage = JpaEventStorage(domainEventEntryRepository)

}